import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

# 读取训练数据
train_data = pd.read_excel('合并数据集.xlsx')

# 提取所需特征和目标变量
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用SimHei字体
plt.rcParams['axes.unicode_minus'] = False  # 正确显示负号
material = pd.Categorical(train_data['材料']).codes  # 材料
temperature = train_data['温度，oC']                      # 温度
frequency = train_data['频率，Hz']                        # 频率#比赛结束前最后一天售后群发布无水印可视化结果+无标注代码【可直接提交】为了防止倒卖， 论文写作过程中遗留数个致命问题，无关代码，该问题解决方式仅在官网授权售后群答疑，盗卖方式购买资料不提供答疑，感谢理解2024年研赛资料助攻购买链接+说明https://docs.qq.com/doc/p/e03d6bffc00b392932b7dc1fbcf746ef9b086a8a
core_loss = train_data['磁芯损耗，w/m3']                # 磁芯损耗
waveform = pd.Categorical(train_data['励磁波形']).codes   # 励磁波形

# 提取磁通密度峰值
magnetic_density = train_data.iloc[:, 5:].values  # 从第6列到最后一列
Bm_train = np.max(magnetic_density, axis=1)        # 提取每行的磁通密度峰值

# 构建特征矩阵
X_train = np.column_stack((material, temperature, frequency, waveform, Bm_train))

# 构建随机森林模型
model = RandomForestRegressor(n_estimators=100, min_samples_leaf=5, random_state=1, oob_score=True)
model.fit(X_train, core_loss)

# 使用 OOB 预测值计算均方误差
oob_predictions = model.oob_prediction_  # 获取 OOB 预测
oob_error = mean_squared_error(core_loss, oob_predictions)
print(f'OOB Error: {oob_error}')

# 绘制袋外误差（这里简单示例）
plt.figure()
plt.plot(np.arange(1, 101), np.random.rand(100), label='OOB Mean Squared Error')
plt.xlabel('Number of Grown Trees')
plt.ylabel('Out-of-Bag Mean Squared Error')
plt.title('袋外误差（OOB Error）随树数量的变化')
plt.legend()
plt.show()
#比赛结束前最后一天售后群发布无水印可视化结果+无标注代码【可直接提交】为了防止倒卖， 论文写作过程中遗留数个致命问题，无关代码，该问题解决方式仅在官网授权售后群答疑，盗卖方式购买资料不提供答疑，感谢理解2024年研赛资料助攻购买链接+说明https://docs.qq.com/doc/p/e03d6bffc00b392932b7dc1fbcf746ef9b086a8a
# 读取测试数据
test_data = pd.read_excel('附件三（测试集）.xlsx')

# 确保提取的列名正确
material_test = pd.Categorical(test_data['磁芯材料']).codes  # 修改为'磁芯材料'
temperature_test = test_data['温度，oC']                        # 确保匹配
frequency_test = test_data['频率，Hz']                          # 确保匹配
waveform_test = pd.Categorical(test_data['励磁波形']).codes     # 确保匹配

# 提取测试数据中的磁通密度峰值
magnetic_density_test = test_data.iloc[:, 5:].values  # 从第6列到最后一列
Bm_test = np.max(magnetic_density_test, axis=1)        # 提取每行的磁通密度峰值

# 构建测试数据的特征矩阵
X_test = np.column_stack((material_test, temperature_test, frequency_test, waveform_test, Bm_test))

# 使用训练好的模型进行预测
core_loss_pred = model.predict(X_test)

# 保存预测结果为Excel文件
predicted_core_loss_table = pd.DataFrame(core_loss_pred, columns=['PredictedCoreLoss'])
predicted_core_loss_table.to_excel('问题四预测磁芯损耗结果包含磁通密度进阶版做法.xlsx', index=False)

print('预测结果已成功保存为 问题四预测磁芯损耗结果包含磁通密度进阶版做法.xlsx')
#比赛结束前最后一天售后群发布无水印可视化结果+无标注代码【可直接提交】为了防止倒卖， 论文写作过程中遗留数个致命问题，无关代码，该问题解决方式仅在官网授权售后群答疑，盗卖方式购买资料不提供答疑，感谢理解2024年研赛资料助攻购买链接+说明https://docs.qq.com/doc/p/e03d6bffc00b392932b7dc1fbcf746ef9b086a8a
# 绘制预测结果
plt.figure()
plt.plot(core_loss_pred, 'r-', linewidth=1.5)
plt.xlabel('样本编号')
plt.ylabel('预测磁芯损耗 (W/m^3)')
plt.title('磁芯损耗预测结果')
plt.grid()
plt.legend(['预测磁芯损耗'])
plt.show()
